home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snpd0492.zip / C_CMNT.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  5KB  |  155 lines

  1. /* Extract comments from a C program source file.
  2. **
  3. ** This program acts as a filter to copy comments in a C source
  4. ** file to the output.  Each comment includes the starting and
  5. ** ending delimiters and is followed by a newline.
  6. **
  7. ** Three #ifdef options are defined:
  8. **   INHIBIT_TRIGRAPHS prevents recognition of trigraphs, which
  9. **      can affect detection of escaped characters,
  10. **      i.e., ??/" is an escaped quote.
  11. **   TRANSLATE_TRIGRAPHS causes the output to have trigraphs
  12. **      converted to the normal C characters.
  13. **   CPP_MODE causes "//" to start a comment.
  14. ** The default for these symbols is undefined, resulting in
  15. ** operation on strict ANSI source, except as noted below.
  16. **
  17. ** What makes this program interesting is that comment detection
  18. ** should be inhibited within strings and character constants.
  19. **
  20. ** Note: The name of a header following #include can, under ANSI,
  21. ** contain any sequence of characters, except \n and the closing
  22. ** > or ".  This program doesn't inhibit comment, string, or character
  23. ** constant detection within the header name, as an ANSI parser must.
  24. **
  25. ** Written by and contributed to the public domain by
  26. ** Thad Smith III,   Boulder, CO,  October 1990.
  27. */
  28.  
  29. #include <stdio.h>
  30.  
  31. #ifndef INHIBIT_TRIGRAPHS        /* default: recognize trigraphs */
  32.  #define getnc()  getnsc(1)       /* get char with trigraph xlate */
  33.  #ifdef TRANSLATE_TRIGRAPHS
  34.   #define getcmtc() getnsc(1)     /* get comment char w/ t.g. xlate */
  35.  #else
  36.   #define getcmtc() getnsc(0)     /* default: no comment t.g. xlate */
  37.  #endif
  38.  
  39. /*
  40. **  get next source character or EOF
  41. */
  42.  
  43. int getnsc(int cvtg)             /* boolean: convert trigraphs */
  44. {
  45.       static int c, nc, nnc;     /* next 3 characters */
  46.  
  47.       /* shift in next source character */
  48.  
  49.       c = nc;  nc = nnc;   nnc = getchar();
  50.  
  51.       /* perform trigraph substitution */
  52.  
  53.       if (cvtg && c == '?' && nc == '?')
  54.       {
  55.             switch (nnc)
  56.             {
  57.             case '=' :
  58.                   c = '#' ;
  59.                   break;
  60.             case '(' :
  61.                   c = '[' ;
  62.                   break;
  63.             case '/' :
  64.                   c = '\\';
  65.                   break;
  66.             case ')' :
  67.                   c = ']' ;
  68.                   break;
  69.             case '\'':
  70.                   c = '^' ;
  71.                   break;
  72.             case '<' :
  73.                   c = '{' ;
  74.                   break;
  75.             case '!' :
  76.                   c = '|' ;
  77.                   break;
  78.             case '>' :
  79.                   c = '}' ;
  80.                   break;
  81.             case '-' :
  82.                   c = '~' ;
  83.                   break;
  84.             default  :
  85.                   return c;        /* no substitution */
  86.             }
  87.             nc = getchar();   nnc = getchar();
  88.       }
  89.       return c;
  90. }
  91.  
  92. #else       /* don't process trigraphs */
  93.  
  94.  #define getnc()   getchar()
  95.  #define getcmtc() getchar()
  96. #endif
  97.  
  98. int main(void)
  99. {
  100.       int pc;  /* previous character      */
  101.       int c;   /* current input character */
  102.  
  103. #ifndef INHIBIT_TRIGRAPHS
  104.       getnc();                                        /* prime the pump */
  105.       getnc();
  106. #endif
  107.       c = getnc();                                    /* get first char */
  108.  
  109.       for (;;)                                  /* in non-comment area */
  110.       {
  111.             switch (c)
  112.             {
  113.             case '/':                     /* possible start of comment */
  114.                   if ((c= getnc()) == '*')      /* process comment */
  115.                   {
  116.                         putchar('/');
  117.                         putchar('*');
  118.  
  119.                         /* copy comment to stdout */
  120.  
  121.                         for (pc = 0; (c = getcmtc()) != EOF &&
  122.                               (putchar(c) != '/' || pc != '*'); pc=c)
  123.                                     ;
  124.                               putchar('\n');
  125. #ifdef CPP_MODE
  126.                   }
  127.                   else if (c == '/')      /*  '//' comment */
  128.                   {
  129.                         putchar('/');
  130.                         putchar('/');
  131.                         while ((c = getcmtc()) != EOF && putchar(c) != '\n')
  132.                               ;
  133. #endif
  134.                   }
  135.                   else  continue;         /* test current char */
  136.                   break;
  137.  
  138.             case '\"':                                /* start of string */
  139.             case '\'':    /* start of (possibly multi-byte) char constant */
  140.                   pc = c;                             /* save delimiter */
  141.                   do                      /* scan through character constant,
  142.                                           ** discarding escape chars
  143.                                           */
  144.                   {
  145.                         while ((c = getnc()) == '\\')
  146.                               getnc();
  147.                   } while (c != pc && c != EOF);
  148.                   break;
  149.             }
  150.             if (c == EOF)
  151.                   return 0;
  152.             else  c = getnc();
  153.       }
  154. }
  155.